# 不能以数字开头
# def 2f():
#     print("2f")

# 不能包含 - 符号
# def a-b():
#     print("a-b")

# 函数中的变量是局部的,函数外不生效
def hi():
    n = 10
    print("n = ", n)


# hi()
# 函数内部定义的n,在函数外部是不能使用的
# print("n : " , n)

# 如果一个文件,同时出现两个函数名称相同的函数,则以就近原则进行调用
def cry():
    print("cry1")


def cry():
    print("cry2")


# cry()


# 5.调用函数的时候,根据函数定义的参数的位置来传递参数,这种传参方式就是位置参数
# 传递的实参和定义的形参顺序和个数是必须一致的,同时定义的形参不需要指定数据类型,会根据传入的实参决定
def car_info(name, price, color):
    print(f"name->{name},price->{price},color->{color}")


# 传递的实参和定义的形参顺序和个数必须一致,否则会报TypeError错误
# car_info("宝马" , 500000 , "red" , 11)

# 6.函数可以有多个返回值,返回数据类型不受限制
def f2(n1, n2):
    return n1 + n2, n1 - n2


# python被称为cpython，其实python是c演变过来的，js的解构也是一样的，所以 其实是相通的
# r1 , r2 = f2(10 , 20)
# print(f"r1->{r1} r2->{r2}")

# 7.函数支持关键字参数,即:函数调用的时候,可以通过 "形参名=实参值" , 形式传递参数，这样可以不受参数传递顺序的限制
def book_info(name, price, author, amount):
    print(f"name->{name} , price->{price} , author->{author} , amount->{amount}")


# 通常调用方式 一一对应
book_info("红楼梦", 60, "曹雪芹", 30000)

# 使用关键字参数进行调用
print("-----------关键字参数-------------")
book_info(name="红楼梦", price=60, amount=50000, author="曹雪芹")

# 虽然说很多东西很方便，但是也是必须有一定的规律的，程序不能解决所有问题，所以，要配合人的使用
# 不要追求完美 没有完美  不要追求永远 没有永远 不要再追求太细节的东西 差不多就行
print("--------混合传递参数--------------")
book_info("红楼梦", 60, amount=60000, author="曹雪芹")


# 函数支持默认参数/缺省参数
# -定义函数的时候,可以给参数提供默认值,调用函数的时候,指定了实参,则以指定为准，如果没有指定,则以默认值为准
# 默认参数，需要放在参数列表的后面呢   这是符合逻辑的
def book_info2(name="<<thinking in python>>", price=66.8, author='龟叔', amount=1000):
    print(f"name->{name} , price -> {price} , author -> {author} , amount -> {amount}")


book_info2()


# - 默认参数，需要放在参数列表的后面
def book_info3(name, price, author='龟叔', amount=1000):
    print(f"name->{name} , price -> {price} , author -> {author} , amount -> {amount}")


book_info3("<<python揭秘>>", 999)


# 错误的写法，有默认值的参数智能写在后面
# def book_info4(name='aaa', price, author = '龟叔' , amount=1000):
#     print(f"name->{name} , price -> {price} , author -> {author} , amount -> {amount}")

def sum(*args):
    print(f"args->{args} 类型是->{type(args)}")
    total = 0
    # 对args进行遍历,即对元组遍历
    for ele in args:
        total += ele
    return total

#调用测试
# result = sum(1,2,3,4)
# print(f"result->{result}")

#函数是可变参数，支持多个关键字参数 也就是多个   形参名=实参值  dict
#比如我们要接受一个人的信息,但是有的信息是不确定的，就可以使用关键字可变参数
def person_info(**kwargs):
    print(f"kwargs->{kwargs} 类型->{type(kwargs)}")
    #遍历kwargs，是一个字典,下面的arg_name 就是取出各个参数名
    for arg_name in kwargs:
        print(f"参数名->{arg_name} 参数值->{kwargs[arg_name]}")

person_info(name="hsp" , age = 18 , email="hsp@qq.com")